/**
 * 心跳基类
 */
export class Heart {
    heartTimeOut; // 心跳计时器
    ServerHeartTimeOut; // 心跳计时器
    timeout = 5000;
    // 重置
    reset() {
        clearTimeout(this.heartTimeOut);
        clearTimeout(this.ServerHeartTimeOut);
    }
    /**
     * 启动心跳
     * @param {Function} cb 回调函数
     */
    start(cb) {
        // console.log('开启心跳')
        this.heartTimeOut = setTimeout((e) => {
            cb(e);
            this.ServerHeartTimeOut = setTimeout((args) => {
                cb(args);
                // 重新开始检测
                this.reset();
                this.start(cb);
            }, this.timeout);
        }, this.timeout);
    }
}
export default class Socket extends Heart {
    ws;
    reconnectTimer; // 重连计时器
    reconnectCount = 10; // 变量保存，防止丢失
    options = {
        url: null,
        heartTime: 5000,
        heartMsg: 'ping',
        isReconnect: true,
        isRestory: false,
        reconnectTime: 5000,
        reconnectCount: 5,
        openCb: (e) => {
            console.log('连接成功的默认回调::::', e);
        },
        closeCb: (e) => {
            console.log('关闭的默认回调::::', e);
        },
        messageCb: (e) => {
            console.log('连接成功的默认回调::::', e);
        },
        errorCb: (e) => {
            console.log('错误的默认回调::::', e);
        } // 错误的回调
    };
    constructor(ops) {
        super();
        Object.assign(this.options, ops);
        this.create();
    }
    /**
     * 建立连接
     */
    create() {
        if (!('WebSocket' in window)) {
            throw new Error('当前浏览器不支持，无法使用');
        }
        if (!this.options.url) {
            throw new Error('地址不存在，无法建立通道');
        }
        this.ws = new WebSocket(this.options.url);
        this.onopen(this.options.openCb);
        this.onclose(this.options.closeCb);
        this.onmessage(this.options.messageCb);
    }
    /**
     * 自定义连接成功事件
     * 如果callback存在，调用callback，不存在调用OPTIONS中的回调
     * @param {Function} callback 回调函数
     */
    onopen(callback) {
        this.ws.onopen = event => {
            // 连接成功后
            clearTimeout(this.reconnectTimer); // 清除重连定时器
            this.options.reconnectCount = this.reconnectCount; // 计数器重置
            // 建立心跳机制，检测连接是否中断
            super.reset();
            super.start(() => {
                // 发送ping，进行检测
                this.send(this.options.heartMsg);
            });
            if (typeof callback === 'function') {
                callback(event);
            }
            else {
                typeof this.options.openCb === 'function' && this.options.openCb(event);
            }
        };
    }
    /**
     * 自定义关闭事件
     * 如果callback存在，调用callback，不存在调用OPTIONS中的回调
     * @param {Function} callback 回调函数
     */
    onclose(callback) {
        this.ws.onclose = event => {
            super.reset();
            // 当非正常销毁时，进行重连
            !this.options.isRestory && this.onreconnect();
            if (typeof callback === 'function') {
                callback(event);
            }
            else {
                typeof this.options.closeCb === 'function' && this.options.closeCb(event);
            }
        };
    }
    /**
     * 自定义错误事件
     * 如果callback存在，调用callback，不存在调用OPTIONS中的回调
     * @param {Function} callback 回调函数
     */
    onerror(callback) {
        this.ws.onerror = event => {
            if (typeof callback === 'function') {
                callback(event);
            }
            else {
                typeof this.options.errorCb === 'function' && this.options.errorCb(event);
            }
        };
    }
    /**
     * 自定义消息监听事件
     * 如果callback存在，调用callback，不存在调用OPTIONS中的回调
     * @param {Function} callback 回调函数
     */
    onmessage(callback) {
        this.ws.onmessage = (event) => {
            // 收到任何消息，重新开始倒计时心跳检测
            super.reset();
            super.start(() => {
                this.send(this.options.heartMsg);
            });
            if (typeof callback === 'function') {
                callback(event);
            }
            else {
                typeof this.options.messageCb === 'function' && this.options.messageCb(event);
            }
        };
    }
    /**
     * 自定义发送消息事件
     * @param {String} data 发送的文本
     */
    send(data) {
        if (this.ws.readyState === this.ws.OPEN) {
            data = JSON.stringify(data);
            this.ws.send(data);
        }
        else if (this.ws.readyState === this.ws.CONNECTING) {
            const _self = this;
            setTimeout(function () {
                _self.send(data);
            }, 1000);
        }
        else {
            this.ws.close();
            this.create();
        }
    }
    /**
     * 连接事件
     */
    onreconnect() {
        if (this.options.reconnectCount > 0 || this.options.reconnectCount === -1) {
            this.reconnectTimer = setTimeout(() => {
                this.create();
                if (this.options.reconnectCount !== -1)
                    this.options.reconnectCount--;
            }, this.options.reconnectTime);
        }
        else {
            // 等于0时，清除重连定时器，重置重连次数。
            clearTimeout(this.reconnectTimer);
            this.options.reconnectCount = this.reconnectCount;
        }
    }
    /**
     * 销毁
     */
    destroy() {
        super.reset();
        clearTimeout(this.reconnectTimer); // 清除重连定时器
        this.options.isRestory = true;
        this.ws.close();
    }
}
